package com.pwt.service;

import com.pwt.common.DataNotFoundException;
import com.pwt.common.ResultCode;
import com.pwt.entity.Attachment;
import com.pwt.repository.AttachmentRepository;
import com.pwt.utils.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.List;

/**
 * Attachment service层
 *
 * @author auto generated
 * @date 2021-09-02 10:43:16
 */
@Service
public class AttachmentService {

    @Autowired
    AttachmentRepository attachmentRepository;

    public String upload(MultipartFile file, HttpServletRequest request) throws IOException {
        String dir = "attachment";
        String fileName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
        String filePath = System.getProperty("user.dir") + dir + File.separator;
        File dict = new File(filePath);
        if(!dict.exists()) {
            dict.mkdirs();
        }
        File dest = new File(filePath + fileName);
        file.transferTo(dest);
        String md5 = FileUtils.getMd5(dest);
        int count = attachmentRepository.countByMd5(md5);
        if(count > 0) {
            dest.deleteOnExit();
            Attachment attachment = attachmentRepository.findByMd5(md5);
            return attachment.getUrl();
        }
        String mimeType = FileUtils.getContentType(fileName.substring(fileName.lastIndexOf(".")));
        String ext = mimeType.split("/")[0];
        Attachment attachment = new Attachment();
        attachment.setMd5(md5);
        attachment.setSha1(FileUtils.getSha1(dest));
        attachment.setPath(filePath + fileName);
        attachment.setThumb(null);
        attachment.setUrl(null);
        attachment.setMime(mimeType);
        attachment.setExt(ext);
        attachment.setName(file.getOriginalFilename());
        attachment.setSize(file.getSize());

        if("image".equals(ext)) {
            BufferedImage sourceImg = ImageIO.read(dest);
            attachment.setWidth(sourceImg.getWidth());
            attachment.setHeight(sourceImg.getHeight());
        }
        attachmentRepository.save(attachment);

        StringBuffer requestURL = request.getRequestURL();
        String servletPath = request.getServletPath();
        String host = requestURL.toString().replaceAll(servletPath,"");
        attachment.setUrl((StringUtils.isBlank(host) ? "" : host) + "/attachment/" + attachment.getId());
        attachmentRepository.save(attachment);
        return attachment.getUrl();
    }

    public void download(String id, HttpServletResponse response) throws DataNotFoundException {
        Attachment attachment = attachmentRepository.findById(id).orElse(null);
        if(attachment == null) {
            throw new DataNotFoundException(ResultCode.DATA_NOT_FOUND);
        }
        String path = attachment.getPath();
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(path);
            OutputStream outputStream = response.getOutputStream();
            if(!"image".equals(attachment.getExt())) {
                response.addHeader("Content-Disposition", "attachment;filename=" + new String(attachment.getName().getBytes()));
            }
            response.addHeader("Content-Length", "" + attachment.getSize());
            response.setContentType(attachment.getMime());
            IOUtils.copy(inputStream,outputStream);
        } catch (FileNotFoundException e) {
            throw new DataNotFoundException(ResultCode.DATA_NOT_FOUND);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
